﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>DevAge Source Pack</title>
    <link href="style.css" type="text/css" rel="stylesheet" />
</head>
<body>
    <h1>
        DevAge Source Pack</h1>
        <small>Library Version: 4.11<br />
        Documentation Version: 1.9</small>

    <ul>
        <li><a href="http://www.devage.com/archive/DevAgeSourcePack4_11.zip">Download binary and source</a></li>
        <li><a href="http://www.devage.com/">Official Web Site</a></li>
    </ul>

    <div id="TOC"></div>

    <h2>Introduction</h2>
    <p>
        DevAgeSourcePack is a set of .NET projects created to extend and add some new features
        to the standard .NET Framework. DevAgeSourcePack is developed as an Open Source
        project, licensed under a MIT style license.</p>
    <p>The documentation for now is poor, I suggest to look at the sample application that you can find inside the zip file for a complete list of features.</p>
    <p>
        DevAgeSourcePack is written in C#, compiled with the Microsoft .NET Framework 2
        and Visual Studio .NET 2005. All the projects are written with fully managed
        code.</p>
    <p>
        The latest version of this project and a forum for help and discussions is available at <a href="http://www.devage.com/" target="_blank">http://www.devage.com/</a>.</p>

    <p>
       I have moved the <code>SourceGrid</code> project, you can find it at <a href="http://sourceforge.net/projects/sourcegrid">http://sourceforge.net/projects/sourcegrid</a>.
        </p>
        
    <h2>Projects</h2>
    <p>
        DevAgeSourcePack is composed by 2 projects, here you can find some details on each
        project and the most important features:</p>
        
    <h3>DevAge.Core</h3>
    <p>
        Contains some common helper classes.</p>
    <ul>
        <li>ComponentModel.Validator namespace - Classes used to validate and convert values.</li>
        <li>Configuration namespace - Classes used to save and restore generic settings.</li>
        <li>IO namespace - Stream and isolated storage classes.</li>
        <li>Data namespace - Some utilities for data access
            <ul>
                <li>Data.FileDataSet class - Class used to save and restore a DataSet from a file.</li>
                <li>Data.SqlCommandBuilder class - Build SQL Server commands from a typed DataSet.</li>
                <li>Data.DataSetHelper - DataSet helper methods.</li>
                <li>...</li>
            </ul>
        </li>
        <li>Text namespace - Some utilities for parsing and writing fixed delimiter files.</li>
        <li>...</li>
    </ul>
    
    <h4>Validator</h4>
    <p>The goal of a <code>Validator</code> class is to organize validation and conversion code in a single class, that can be used with user interface editors or for any validation and conversion code.<br />
    Each <code>Validator</code> must implement the <code>IValidator</code> interface.</p>
    <img src="ValidatorClassDiagram.png" alt="Validator Class Diagram" />
    <ul>
        <li><code>IValidator</code> - The interface that all validator classes must implement.</li>
        <li><code>ValidatorBase</code> - An abstract class that can be used as a base validator class.</li>
        <li><code>ValidatorTypeConverter</code> - A validator that use a system <code>TypeConverter</code> to convert and validate.</li>
        <li><code>ValueMapping</code> - A class that can be used to implement customized conversion.</li>
    </ul>
    <p>Currently the <code>ValidatorTypeConverter</code> is the most important class. Can be used to convert to and from a string any type that have a <code>TypeConverter</code>.</p>
    <p>For more information about <code>TypeConverter</code> see this <a href="http://msdn2.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx">MSDN article</a>.</p>
    <p>In the code belowe you can see how to use a validator:</p>
    <pre>
DevAge.ComponentModel.Validator.ValidatorTypeConverter dblConverter = 
    new DevAge.ComponentModel.Validator.ValidatorTypeConverter(typeof(double));
dblConverter.CultureInfo = System.Globalization.CultureInfo.InvariantCulture;

string strVal = dblConverter.ValueToString(50.4);

double dblVal = (double)dblConverter.StringToValue("46.78");
    </pre>
    
    <h4>SqlCommandBuilder</h4>
    <p>The <code>DevAge.Data.SqlClient.SqlCommandBuilder</code> class can be used to generate the SqlCommands to insert, update or delete records based on the structure of a DataSet.</p>
    <p>Suppose to have defined a DataTable like this:</p>
    <img src="SampleTable.png" alt="SampleTable" />
    <p>You can generate the SQL commands with this code:</p>
    <pre>
System.Text.StringBuilder outText = new System.Text.StringBuilder();    
DevAge.Data.SqlClient.SqlCommandBuilder cmdBuilder = new DevAge.Data.SqlClient.SqlCommandBuilder(table);

outText.AppendLine(cmdBuilder.GetDeleteCommand().CommandText);
outText.AppendLine(cmdBuilder.GetUpdateCommand().CommandText);
outText.AppendLine(cmdBuilder.GetInsertCommand().CommandText);
txtSqlOutput.Text = outText.ToString();
    </pre>
    <p>This is the output:</p>
    <pre>
DELETE [Customers] WHERE [CustomerID] = @p0
UPDATE [Customers] SET [CompanyName] = @p1,[ContactName] = @p2,[ContactTitle] = @p3,[Address] = @p4,
                [City] = @p5,[Region] = @p6,[PostalCode] = @p7,[Country] = @p8,[Phone] = @p9,
                [Fax] = @p10 
                WHERE [CustomerID] = @p0
INSERT INTO [Customers] ([CustomerID],[CompanyName],[ContactName],[ContactTitle],[Address],
                [City],[Region],[PostalCode],[Country],[Phone],[Fax]) 
            VALUES (@p0,@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8,@p9,@p10)
    </pre>
    <p>I have only printed the CommandText property of the SqlCommand, but you can directly use the generated SqlCommand with a SqlDataAdapter. The SqlCommand have the parameters with all the right source column defined so the mapping betwen the SQL and the DataTable is automatic.</p>
    <p>You can for example write this method to save a generic table to a SQL Server database:</p>
    <pre>
public void UpdateDataTable(DataTable table)
{
    SqlDataAdapter adapter = new SqlDataAdapter();
    DevAge.Data.SqlClient.SqlCommandBuilder builder = new DevAge.Data.SqlClient.SqlCommandBuilder(table);
    adapter.InsertCommand = builder.GetInsertCommand();
    adapter.InsertCommand.Connection = mTransaction.Connection;
    adapter.InsertCommand.Transaction = mTransaction;
    adapter.InsertCommand.CommandTimeout = mCommandTimeout;

    adapter.UpdateCommand = builder.GetUpdateCommand();
    adapter.UpdateCommand.Connection = mTransaction.Connection;
    adapter.UpdateCommand.Transaction = mTransaction;
    adapter.UpdateCommand.CommandTimeout = mCommandTimeout;

    adapter.DeleteCommand = builder.GetDeleteCommand();
    adapter.DeleteCommand.Connection = mTransaction.Connection;
    adapter.DeleteCommand.Transaction = mTransaction;
    adapter.DeleteCommand.CommandTimeout = mCommandTimeout;

    adapter.Update(table);
}    
    </pre>
    
    <p>Note that the <code>SqlCommandBuilder</code> simply use the informations defined in the DataTable, without reading the real DB structure. Of course you must define the DataTable to match exactly the real DB structure.
    <br />
    The DataSet must be defined with the right primary keys and the correct columns.
    <br />
    For now only Sql Server is supported.</p>
    
    <h4>StreamDataSet</h4>
    <p><code>DevAge.Data.StreamDataSet</code> is an helper class that can be used to serialize and deserialize <code>DataSet</code> to and from a <code>Stream</code>.</p>
    <p>The problem with classic DataSet serialization using built-in xml serialization or binary serialization is that the result are quite heavy because internally the data are saved with an xml format that it is by its nature quite redundant. 
    With the <code>StreamDataSet</code> you can create a compact image of the DataSet using a customized binary serialization.<br />
    Basically my idea is to use the classic xml format for the schema, and a binary format for the data.</p>
    <p>The current implementation create an image with this structure:</p>
    <img src="StreamDataSetOutput.png" alt="StreamDataSet Output" />
    <p>Each value is composed by a byte to indicate if is null and the actual data, that can be any .NET primitive type. <br />
    Note that the header is composed by the classic xml schema generated from the DataSet, this is very useful because in this way the stream contains the schema of the data and can be used at deserialization.</p>
    <p>When deserializing the stream you can merge the schema with the one embedded in the stream or use your new DataSet schema. In this way you can easily support schema changes (for example you can remove columns or entire tables from the new schema).</p>
    <p>In the code below you can see a simple example on how to serialize a DataSet:</p>
    <pre>
//Serialize the DataSet 
// (where 'ds' is the dataset to serialize and 'buffer' is a byte[] variable)
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{
    DevAge.Data.StreamDataSet.Write(stream, ds, DevAge.Data.StreamDataSetFormat.Binary);

    buffer = stream.ToArray();
}
    </pre>
    <p>And now deserialize it:</p>
    <pre>
//Deserialize the DataSet (where 'buffer' is the previous serialized byte[])
System.Data.DataSet deserializedDs = new System.Data.DataSet();
using (System.IO.MemoryStream stream = new System.IO.MemoryStream(buffer))
{
    DevAge.Data.StreamDataSet.Read(stream, deserializedDs,
                 DevAge.Data.StreamDataSetFormat.Binary, true);
}
    </pre>
        
        
    <h4>FixedLength parser/writer</h4>
    <p>The <code>DevAge.Text.LineParser</code> and <code>LineWriter</code> classes are used to parse and generate fixed length files or string.</p>
    <p>Suppose that you have a legacy file like this:</p>    
    <pre>
ACOD12006100858.80DAVIDE    12.75
ACOD22006020849.05HOMER     00.25
BCOD32004090812.25PETER     05.00
    </pre>
    <p>Where each field is a fixed length field with the following structure:</p>
    <img src="FixedLengthSample.png" alt="FixedLengthSample" />
    <p>You can define a class to map each field to a property of a class like this:</p>
    <pre>
public class SampleClass
{
    private string mField0;
    private string mField1;
    private DateTime mField2;
    private double? mField3;
    private string mField4;
    private decimal mField5;

    [DevAge.Text.FixedLength.Field(0, 1)]
    public string LineType
    {
	    get{return mField0;}
	    set{mField0 = value;}
    }
    [DevAge.Text.FixedLength.Field(1, 4)]
    public string Code
    {
	    get{return mField1;}
	    set{mField1 = value;}
    }
    [DevAge.Text.FixedLength.Field(2, 8)]
    [DevAge.Text.FixedLength.ParseFormat(DateTimeFormat="yyyyMMdd")]
    [DevAge.Text.FixedLength.ValueMapping("00000000", "00010101")]
    public DateTime BirthDay
    {
	    get{return mField2;}
	    set{mField2 = value;}
    }
    [DevAge.Text.FixedLength.Field(3, 5)]
    [DevAge.Text.FixedLength.ParseFormat(NumberFormat="00.00")]
    public double? Points
    {
	    get{return mField3;}
	    set{mField3 = value;}
    }
    [DevAge.Text.FixedLength.Field(4, 10)]
    public string Name
    {
	    get{return mField4;}
	    set{mField4 = value;}
    }
    [DevAge.Text.FixedLength.Field(5, 5)]
    [DevAge.Text.FixedLength.ParseFormat(NumberFormat = "00.00")]
    public decimal Value
    {
        get { return mField5; }
        set { mField5 = value; }
    }
}
    </pre>
    <p>You can note that I have defined a standard .NET class with some additional attributes.</p>
    <ul>
        <li>The <code>DevAge.Text.FixedLength.Field</code> attribute is used to specify the field number and the length.
        </li>
        <li>The <code>DevAge.Text.FixedLength.ParseFormat</code> attribute is used to specify an optional custom format for the field.</li>
    </ul>
    <p>You can then use this code to parse a single line (the <code>line</code> variable contains a single line of the previous file):</p>
    <pre>
DevAge.Text.FixedLength.LineParser parser = new DevAge.Text.FixedLength.LineParser(typeof(SampleClass));
parser.LoadLine(line);

SampleClass sampleClass = new SampleClass();
parser.FillLineClass(sampleClass);
    </pre>
    <p>I have created an instance of the <code>DevAge.Text.FixedLength.LineParser</code> passing in the constructor the type of the class that contains the structure to parse as specified by the attributes. 
    <br />
    Load a single line using the <code>LoadLine</code> method and then you can fill an existing instance of the class using the <code>FillLineClass</code> method.</p>
    <p>In a similar way you can generate a line using an existing populated class (where the <code>sampleClass</code> variable is a populated and valid instance of the SampleClass class):</p>
    <pre>
DevAge.Text.FixedLength.LineWriter writer = new DevAge.Text.FixedLength.LineWriter(typeof(SampleClass));

line = writer.CreateLineFromClass(sampleClass);
    </pre>
    <p>You can easily iterate on a file and parse all the line or create a new file writing each time a new line.</p>    
    
    <p>You can use the <code>DevAge.Text.FixedLength.ValueMapping</code> to automatically convert a value to another value. I have used for example to convert a date time defined like '000000000' to a datetime '00010101'.</p>
    <p>You can also define Nullable field (like double?) to allow empty field.</p>
    
    <h3>DevAge.Windows.Forms</h3>
    <p>
        Contains most of the drawing code used by SourceGrid and some commons Windows Forms controls.<br />
        There is also a <code>DevAge.Drawing.VisualElements</code> namespace will all the classes used to draw themed and not themed elements (text, images, UI elements, ...).</p>
    
    <h4>VisualElements</h4>
    <p>The <code>DevAge.Drawing.VisualElements</code> namespace contains the base drawing code used for many other controls (including SourceGrid).</p>
    <p>Basically I have created a set of classes to draw each visual elements. All VisualElements implements the <code>IVisualElement</code> interface:</p>
    <pre>
public interface IVisualElement : ICloneable
{
    AnchorArea AnchorArea
    {
        get;
        set;
    }

    RectangleF GetDrawingArea(MeasureHelper measure, System.Drawing.RectangleF area);

    System.Drawing.SizeF Measure(MeasureHelper measure, System.Drawing.SizeF minSize, System.Drawing.SizeF maxSize);

    void Draw(GraphicsCache graphics, System.Drawing.RectangleF area);

    void Draw(GraphicsCache graphics, System.Drawing.RectangleF area, out System.Drawing.RectangleF drawingArea);

    VisualElementList GetElementsAtPoint(MeasureHelper measure, System.Drawing.RectangleF area, PointF point);
}
    </pre>
    
    <p>Below an overview of the classes. <a href="VisualModelsClassDiagram.png" target="_blank">Click here to zoom the image</a></p>
    <img src="VisualModelsClassDiagramSmall.png" alt="VisualModels Class Diagram" />
    
    <h4>DevAgeTextBox</h4>
    <p><code>DevAgeTextBox</code> is a Windows Forms control that derive from the standard <code>TextBox</code> control.
    Its main feature is the ability to use a <code>Validator</code> class for validation and conversion code.</p>
    <p>Let's see a basic example:</p>
    <pre>
//Create a validator class
DevAge.ComponentModel.Validator.ValidatorTypeConverter validator = 
        new DevAge.ComponentModel.Validator.ValidatorTypeConverter(typeof(int));
        
//Assign the validator to an existing DevAgeTextBox control (txtControl)
txtControl.Validator = validator;
txtControl.Value = 0;
    </pre>
    
    <h4>DevAgeComboBox</h4>
    <p>The <code>DevAgeComboBox</code> is a Windows Forms control derived from the standard <code>ComboBox</code>.
    The main feature of <code>DevAgeComboBox</code> is the ability to use a <code>Validator</code> class.<br />
    A <code>Validator</code> class is used to implement validation and conversion code.</p>
    
    <p>Let's see a basic example:</p>
    <pre>
//Create a validator class
DevAge.ComponentModel.Validator.ValidatorTypeConverter validator = 
        new DevAge.ComponentModel.Validator.ValidatorTypeConverter(typeof(int));
        
//Declare an array of int and assign it to the StandardValues property
int[] intValues = new int[]{ 0, 1, 2, 3 };
validator.StandardValues = intValues;

//Assign the validator to an existing DevAgeComboBox control (cmbControl)
cmbControl.Validator = validator;
cmbControl.Value = 0;
    </pre>
    <p>In the above example I have created a simple combobox with a list of int values.</p>
    
    <p>You can use any kind of values: enum, string, complex objects, ... 
    You can also customize the display string used inside the combobox, using the <code>ValueMapping</code>, here a more complex example:</p>
    <pre>
//Create a validator
DevAge.ComponentModel.Validator.ValidatorTypeConverter customValidator = 
        new DevAge.ComponentModel.Validator.ValidatorTypeConverter(typeof(int));

//Assign a list of available values
int[] intValues = new int[] { 0, 1, 2, 3 };
customValidator.StandardValues = intValues;

//Create a ValueMapping class used to convert a value to another specific value specified
DevAge.ComponentModel.Validator.ValueMapping mapping = new DevAge.ComponentModel.Validator.ValueMapping();
mapping.DisplayStringList = new string[] { "Zero", "One", "Two", "Three" };
mapping.ValueList = intValues;
mapping.SpecialType = typeof(string);
mapping.SpecialList = mapping.DisplayStringList;
mapping.ThrowErrorIfNotFound = false;

//Bind the ValueMapping to the Validator
mapping.BindValidator(customValidator);

cmbCustomDisplay.Validator = customValidator;
cmbCustomDisplay.Value = 0;
cmbCustomDisplay.FormatValue = true;
    </pre>
    
    
    
    <h3>TestApp</h3>
    <p>
        Sample application.</p>

    <h2>References</h2>
    <p>Currently DevAgeSourcePack doesn't have any special references other than the standard .NET 2 system assemblies.</p>


    <h2>History</h2>
    <h3>4.11 (17 Jan 2009)</h3>
    <ul>
	    <li>Converted the solution and all the projects to Visual Studio 2008.</li>
        <li>Converted any DbNull value to null when reading and writing value using the BoundDataView class.</li>
    </ul>
    <h3>4.10 (16 Oct 2007)</h3>
    <ul>
        <li>Fixed a bug in the DevAgeComboBox when used with data binding.</li>
    </ul>
    <h3>4.9 (2 Jun 2007)</h3>
    <ul>
        <li>Removed the TaskListDialog class (no more used).</li>
        <li>Removed the activity related class (no more used).</li>
        <li>Fixed the TextGDI class to use a new StringFormat based on GenericDefault and not the default GenericDefault instance.</li>
        <li>Added the Serializable attribute to the AnchorArea, BorderLine, Padding, RectangleBorder, RoundedRectangle.</li>
        <li>Fixed the DropDownButton VisualElement to correctly draw and measure the drop down button of a combobox.</li>
    </ul>
    <h3>4.8 (6 May 2007)</h3>
    <ul>
        <li>Fixed a bug in the TextBoxUITypeEditor when the text is not valid, expecially for the DateTime editor (1615918).</li>
        <li>Renamed IBindedList to IBoundList</li>
        <li>Renamed BindedListBase to BoundListBase</li>
        <li>Renamed BindedList to BoundList</li>
        <li>Renamed BindedDataView to BoundDataView</li>
        <li>Fixed the BoundList Sort method to correctly sort using a descending order</li>
        <li>Now the BoundList support any IList class</li>
        <li>Changed some code for the BoundList classes. Added a base interface IBoundList and moved some code to the BoundListBase for a better extendibility.</li>
    </ul>    
    <h3>4.6 (15 April 2007)</h3>
    <ul>
        <li>Fixed a bug in the RectangleBorder drawing code</li>
        <li>Fixed a bug in the Measure algorithm of VisualElements</li>
    </ul>
    <h3>4.5 BETA (18 March 2007)</h3>
    <ul>
        <li>Added an example and documentation for the DevAgeComboBox control on how to use custom display and ValueMapping.
        See DevAgeComboBox section on this article.</li>
        <li>Fixed the DevAgeComboBox control to correctly show the display string when required</li>
        <li>Improved documentation</li>
        <li>Renamed DevAge.Drawing.Border to DevAge.Drawing.BorderLine and changed the BorderLine.Width variable from int to float.</li>
        <li>Optimized drawing performance of the DevAge.Drawing.RectangleBorder class</li>
        <li>Removed some obsolete classes</li>
        <li>New schema version using an automatic revision and build number</li>
	    <li>Fixed a bug on the DevAge.Data.StreamDataSet to correctly read binary dataset also after removing a table from the destination schema.</li>
	    <li>Added DevAge.ComponentModel.BindedListBase, BindedDataView and BindedList to create a common layer for list binding support.</li>
	    <li>Optimized Drawing performance of the TextRendering and TextGDI (minor improvements)</li>
    </ul>
        
    <h3>4.0.0.8 BETA (10 Nov 2006)</h3>
    <ul>
        <li>Removed the reference from ODL.dll, that it is not used anymore.</li>
        <li>Added support for flat headers using the BackgroundColorStyle property of the Header, ColumnHeader and RowHeader VisualElements.</li>
        <li>Changed some VisualElements classes for a better customization.</li>        
        <li>Renamed IVisualElementBase to IVisualElement</li>
        <li>Changed the VisualElements to be serializable</li>
    </ul>

    <h3>4.0.0.5 BETA (13 Oct 2006)</h3>
    <ul>
        <li>Fixed a bug when using the &amp; character inside a text considered an hot key character.</li>
        <li>Removed the SendCharExact class that has some problems with international keyboards.</li>
    </ul>
    
    <h3>4.0.0.4 BETA (8 Oct 2006)</h3>
    <ul>
        <li>Replaced ParseFormatAttribute.DoubleFormat with ParseFormatAttribute.NumberFormat for DevAge.Text.FixedLength parser.</li>
        <li>Added support for decimal data type in the DevAge.Text.FixedLength parser.</li>
        <li>Added support for Nullable types in the DevAge.Text.FixedLength parser.</li>
        <li>Fixed the StandardValueAttribute attribute for DevAge.Text.FixedLength parser.</li>
        <li>Fixed a bug in the measure size of the TextRenderer Visual Element.</li>
    </ul>
    
    <h3>4.0.0.2 BETA (1 Oct 2006)</h3>
    <p>This is the new version compiled with .NET 2. There are many new features and improvements. I have merged some of the projects and moved the SourceGrid project.</p>
    
    <p>In this release I have tried
        to aggregate some of the old projects to only these 2 projects for a more simpler
        development and redistribution. I have also moved the <code>SourceGrid</code> project,
        you can find it at <a href="http://sourceforge.net/projects/sourcegrid">http://sourceforge.net/projects/sourcegrid</a>.</p>
    
    <h3>
        1.0.0.8 (13 Feb 2006)</h3>
    <p>
        AssemblyVersion: 1.0.0.8, FileVersion <b>1.0.0.8</b>.</p>
    <ul>
        <li>Fixed a bug when using DataGrid for Object column type.</li>
        <li>Fixed a bug when using RowHeight or ColumnWidth 0 with virtual grid.</li>
        <li>Fixed a bug when drawing disable image, when image parameter is null.</li>
        <li>Added the OwnerDrawSelectionBorder property to the View class to don't draw the
            selection border for special cells (like the Button)</li>
        <li>Fixed the Button cell to correctly call the Execute event (removed the Unselectable
            controller)</li>
        <li>Fixed a bug in the DataGrid to allow using Drag and Drop and Clipboard, and changed
            the editing code. (see sample 43)</li>
        <li>Added OnValueChanging event.</li>
    </ul>
    <h3>
        1.0.0.7 (10 Jan 2006)</h3>
    <p>
        AssemblyVersion: 1.0.0.7, FileVersion <b>1.0.0.7</b>.</p>
    <ul>
        <li>Added the Unselectable Controller to the Button, to make it clickable but not selectable,
            so now don't draw the selection border.</li>
        <li>Fixed a bug when drawing the focus cells on cells with row/col span</li>
        <li>Fixed a bug when using CheckBox cell with column or row span.</li>
        <li>Fixed a bug on drag and drop when removing rows.</li>
        <li>Minor code review.</li>
        <li>Improved some parts of the documentation (Editor).</li>
    </ul>
    <h3>
        1.0.0.6 (9 Jan 2006)</h3>
    <p>
        AssemblyVersion: 1.0.0.6, FileVersion <b>1.0.0.6</b>.</p>
    <ul>
        <li>Fixed a bug with the scrollbars, CustomScrollControl.RecalcCustomScrollBars. Fix
            a bug when minimize the form or with a small form client area.</li>
        <li>Fixed a bug with the EditorNumericUpDown for correctly use the constructor parameter
            mximum, minimum and increment.</li>
        <li>Added property AcceptsInputChar to be used with the IsInputChar method, to catch
            all character in the grid. Used to fix a problem with Access keys/Shortcut keys,
            for example when you have a button with a Access Key specified in a form.</li>
        <li>Fixed some minor bugs in the Validator classes</li>
        <li>Little reviews of the code and xml comments</li>
        <li>Added namespace DevAge.Text.FixedLength for parsing and writing fixed length text</li>
        <li>Changed to virtual some methods of the ArrayGrid class</li>
        <li>Added DevAge.Patterns.Activity class used to execute synchronous and asynchronous
            activities.</li>
    </ul>
    <h3>
        1.0.0.1 (16 Nov 2005)</h3>
    <p>
        AssemblyVersion: 1.0.0.0, FileVersion <b>1.0.0.1</b>.</p>
    <ul>
        <li>Fixed bug in the SendCharExact method to allow {, }, [, ] characters</li>
        <li>SourceGrid: Fixed CheckBox cell when to correctly calls edit events (Start and End
            editing).</li>
        <li>SourceGrid: Fixed bug when minimize the form or when set a small client area fr
            the grid.</li>
        <li>SQLCommandBuilder: Fixed a bug in the generation of the SQL code for multiple primary
            key columns</li>
        <li>Added sample 33 to test SQL Command Builder</li>
        <li>Fixed sample 1 when removing multiple lines</li>
        <li>Added FAQ documentation section</li>
    </ul>
    <h3>
        1.0.0.0 (03 Nov 2005)</h3>
    <ul>
        <li>Fixed TextBoxUITypeEditor constructor when the Type doesn't have a UITypeEditor
            associated.</li>
        <li>Fixed starting edit with special characters and CAPS LOCK key.</li>
        <li>Fixed copy and paste from excel.</li>
        <li>Fixed clipboard Cut feature.</li>
        <li>Extended class ValueMapping for more flexibility with ComboBox editor and Key-Value
            feature. See example 41, (column ExternalID)</li>
        <li>Renamed some methods:
            <ul>
                <li>FocusPosition -> ActivePosition</li>
                <li>ChangeFocusEventArgs -> ChangeActivePositionEventArgs</li>
                <li>SelectionChangeFocusEventHandler -> ChangeActivePositionEventHandler</li>
                <li>Focused -> IsActive</li>
                <li>InternalApplyEdit -> ApplyEdit</li>
                <li>EditExceptionEventArgs -> ExceptionEventArgs</li>
                <li>EditExceptionEventHandler -> ExceptionEventHandler</li>
            </ul>
        </li>
        <li>Removed IEditor interface, now there is only the base class EditorBase.</li>
        <li>Changed method InternalStartEdit and InternalEndEdit to internal.</li>
        <li>Added OnEditStarted for the Cell Controller</li>
        <li>Changed DataGrid editing code with support to BeginEdit, EndEdit and CancelEdit</li>
        <li>Added DataGrid row validation code based on DataTable rules.</li>
        <li>Minor performance improvements</li>
        <li>Some minor bugs fixed</li>
        <li>Added example 43</li>
    </ul>
    <h3>
        0.81.0.0 (15 Sep 2005)</h3>
    <ul>
        <li>Second beta version of DevAgeSourcePack.</li>
        <li>Many SourceGrid improvements and reviewed classes.</li>
        <li>Some bugs fixed.</li>
    </ul>
    <h3>
        0.50.0.0 (24 May 2005)</h3>
    <ul>
        <li>First beta version of DevAgeSourcePack.</li>
    </ul>
    <p>
        DevAgeSourcePack is an evolution of SourceGrid 2 and SourceLibrary projects, for
        informations about these projects look at <a href="http://www.devage.com">www.devage.com</a>.</p>
        
        
    <h2>
        License</h2>
    <p>
        DevAgeSourcePack License (MIT style)</p>
    <p>
        Copyright (c) 2006 www.devage.com, Davide Icardi</p>
    <p>
        Permission is hereby granted, free of charge, to any person obtaining a copy of
        this software and associated documentation files (the "Software"), to deal in the
        Software without restriction, including without limitation the rights to use, copy,
        modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
        and to permit persons to whom the Software is furnished to do so, subject to the
        following conditions:</p>
    <ul>
        <li>The above copyright notice and this permission notice shall be included in all copies
            or substantial portions of the Software. </li>
    </ul>
    <p>
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
    PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    USE OR OTHER DEALINGS IN THE SOFTWARE.
    </p>

</body>
</html>
